const fs = require("fs");
const readline = require('readline');
const { MerkleTree } = require('merkletreejs')
const crypto = require('crypto');

function sha256(data) {
  return crypto.createHash('sha256').update(data).digest()
}

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
console.log('solving:' + process.argv[2] + 'and saving to ' + process.argv[3]);
fs.readFile(process.argv[2], "utf8", (err, jsonString) => {
  if (err) {
    console.log("File read failed:", err);
  } else {
    json = JSON.parse(jsonString);
    // console.log(json);
    console.log(json.merkle_index);
    console.log("which parameter do you want to disclose,please input the index(using space to seprate)!");
    rl.question('input >', function (index) {
      res_indexs = index.split(" ").map(index => parseInt(index));
      res = {};
      res.count = json.merkle_index.length;
      res.merkle_root = json.merkle_root;
      res.merkle_root_signature = json.merkle_root_signature;
      res.salt_seed = json.salt_seed;
      res.sep = json.sep;
      res.did = json.method + ":" + json.id;
      res.indices = res_indexs.map(index => {
        return {
          index: index,
          name: json.merkle_index[index],
          value: json[json.merkle_index[index]]
        }
      });

      var salt = json.salt_seed;
      var leaves = json.merkle_index.map(it => {
        // console.log(json[it])
        salt = sha256(salt).toString("hex");
        return sha256(json[it] + json.sep + salt);
      })

      const tree = new MerkleTree(leaves, sha256);
      console.log('tree root:', tree.getRoot().toString('hex'))
      const proof = tree.getMultiProof(res_indexs);
      // console.log(new MerkleTree([], sha256).verifyMultiProof(tree.getRoot()
      //   , res_indexs, res_indexs.map((index) => leaves[index]), leaves.length, proof));
      // console.log(proof);
      res.proof = proof.map(buff => buff.toString("hex"));
      console.log(res);
      fs.writeFile(process.argv[3], JSON.stringify(res), err => {
        if (err) {
          console.log('Error writing ' + process.argv[3], err)
        } else {
          console.log('Successfully wrote ' + process.argv[3])
        }
      })
      rl.close();
    });
  }
});
